package com.github.ecbp.user.service.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.ecbp.common.constant.CacheKeyConstant;
import com.github.ecbp.common.redis.RedisUtil;
import com.github.ecbp.common.resp.NameVo;
import com.github.ecbp.common.security.config.ControllerMethodScanner;
import com.github.ecbp.common.security.vo.UrlResource;
import com.github.ecbp.user.service.config.AdminSecurityConfig;
import com.github.ecbp.user.service.dto.ResourceDto;
import com.github.ecbp.user.service.service.PermissionService;
import com.github.ecbp.user.service.service.ResourceService;
import com.github.ecbp.user.service.service.RoleService;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Set;

@Component
public class ResourceJobHandler {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private ResourceService resourceService;

    @Autowired
    protected RoleService roleService;

    @Autowired
    private AdminSecurityConfig adminSecurityConfig;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 定时器,扫描缓存中的未处理的(新增的)接口地址信息(资源)
     * 将其保存到t_resource表中
     *
     * @param param
     * @return
     * @throws Exception
     */
    @XxlJob("resourceInitProcess")
    public ReturnT<String> resourceInitProcess(String param) throws Exception {
        try {
            XxlJobLogger.log("XXL-JOB,param {}", JSONObject.toJSON(param));

            Set<Long> permissionIds = new HashSet<>();
            final NameVo nameVo = permissionService.listDefault();

            for (; ; ) {
                String value = redisUtil.srandmember(ControllerMethodScanner.UN_HANDLED_URL);
                if (!StringUtils.isEmpty(value)) {
                    XxlJobLogger.log("待新增资源信息, param {}", value);
                    String[] sp = value.split(CacheKeyConstant.PATH_SEPARATOR);
                    if (sp.length == 2) {
                        ResourceDto resourceDTO = new ResourceDto();
                        resourceDTO.setProjectName(sp[0]);
                        resourceDTO.setUrl(sp[1]);
                        resourceDTO.setPermissionStatus(false);
                        resourceDTO.setPermissionId(nameVo.getId());

                        String detail = redisUtil.hget(ControllerMethodScanner.URL_DETAIL, value);
                        if (!StringUtils.isEmpty(detail)) {
                            UrlResource resource = JSON.parseObject(detail, UrlResource.class);
                            if (null != resource) {
                                resourceDTO.setName(resource.getName());
                                resourceDTO.setDescription(resource.getDescription());
                            }
                        }
                        if (StringUtils.isEmpty(resourceDTO.getName())) {
                            resourceDTO.setName(resourceDTO.getUrl());
                        }
                        Boolean result = resourceService.saveInfo(resourceDTO);
                        permissionIds.add(resourceDTO.getPermissionId());
                        XxlJobLogger.log("新增资源操作, param {} {}", result, JSONObject.toJSON(resourceDTO));
                    }
                    redisUtil.smove(ControllerMethodScanner.UN_HANDLED_URL, ControllerMethodScanner.HANDLED_URL, value);
                    redisUtil.hdel(ControllerMethodScanner.URL_DETAIL, value);
                } else {
                    break;
                }
            }

            if (!CollectionUtils.isEmpty(permissionIds)) {
                adminSecurityConfig.reloadTotalPermission();
                permissionService.reloadUserPermission(permissionIds);
            }

            return ReturnT.SUCCESS;
        } catch (Exception e) {
            XxlJobLogger.log(e);
            return ReturnT.FAIL;
        }
    }
}